package com
{

	
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	import mx.controls.Alert;
	import mx.events.ValidationResultEvent;
	import mx.validators.NumberValidator;
	
	import spark.components.TextInput;
	
	public class NumericTextInput extends TextInput
	{
		private var _notation:String = "dot";
		private var puntoVirgolaNotation:String = ".";
		private var _value:Number;
		private var _restrictNumericText:String = "0-9\\-";
		private var stringEntry:String = null;
		private var _sizeDecimalPart:int = -1;
		private var _oldValue:String;
		private var numberValidator:NumberValidator;
		private var _minValue:Number; 
		private var _maxValue:Number;
		private var _required:Boolean=false;
		private var _isValid:Boolean=false;
		private var _emptyValue:String="-999";

		public function get emptyValue():String
		{
			return _emptyValue;
		}

		public function set emptyValue(value:String):void
		{
			_emptyValue = value;
		}

		override public function set text (value:String):void {
			if (value!=_emptyValue){
				super.text = value;
				//_value=Number(value);
			}
			else
				super.text = null
			
			// Trigger bindings to textChanged.
			dispatchEvent(new Event("textChanged"));
		
		}
		
		public function get isValid():Boolean
		{
			return _isValid;
		}

		public function set isValid(value:Boolean):void
		{
			_isValid = value;
		}


		public function get required():Boolean
		{
			return _required;
		}

		public function set required(value:Boolean):void
		{
			_required = value;
		}
		
		
		public function get minValue():Number
		{
			
			return _minValue;
			
		}
		public function set minValue(value:Number):void
		{
			_minValue=value;
			numberValidator.minValue=value
			numberValidator.lowerThanMinError = "valore ammesso ("+minValue.toString()+"-"+maxValue.toString()+")"
			numberValidator.exceedsMaxError	= "valore ammesso ("+minValue.toString()+"-"+maxValue.toString()+")"
		}
		public function get maxValue():Number
		{
			return _maxValue;
		}
		public function set maxValue(value:Number):void
		{
			_maxValue=value;
			numberValidator.maxValue=maxValue;
			numberValidator.lowerThanMinError = "valore ammesso ("+minValue.toString()+"-"+maxValue.toString()+")"
			numberValidator.exceedsMaxError	= "valore ammesso ("+minValue.toString()+"-"+maxValue.toString()+")"
		}
		//include "OCComponentImpl.as";
		
		public function NumericTextInput():void
		{
			this.addEventListener(KeyboardEvent.KEY_DOWN, keyDownEvent);
			this.addEventListener(KeyboardEvent.KEY_UP, keyUpEvent);
			this.restrict = _restrictNumericText;
			this.addEventListener(Event.CHANGE, changeEvent);
			
			numberValidator = new NumberValidator(); 
			numberValidator.minValue=-9999999999999999999999
			numberValidator.maxValue= 9999999999999999999999
			numberValidator.source=this;
			numberValidator.property = "text"; 
			numberValidator.trigger=this;
			numberValidator.triggerEvent=Event.CHANGE;
			numberValidator.required=required;
			numberValidator.addEventListener(ValidationResultEvent.VALID, numberValid); 
			numberValidator.addEventListener(ValidationResultEvent.INVALID, numberInvalid); 
			numberValidator.integerError ="valore non ammesso"
			numberValidator.lowerThanMinError= " "
			numberValidator.exceedsMaxError = "valore non ammesso max "	
			numberValidator.requiredFieldError= "non" 	
			
		}
		
		public function get sizeDecimalPart():int
		{
			return _sizeDecimalPart;
		}
		
		public function set sizeDecimalPart(value:int):void
		{
			_sizeDecimalPart = value;
			checkDecimalPart();
		}
		
		public function get value():Object
		{
			
			return _value;
			//}
		}
		public function set value(value:Object):void
		{
			var number:String;
			
			if (value == null) {
				_value = NaN;
				this.text = "";
			} else if (value is Number) {
				if (isNaN(Number(value))) {
					_value = NaN;
					this.text = "";
				} else {
					_value = Number(value);
					number = value.toString();
					this.text = number.replace(".", puntoVirgolaNotation);
					checkDecimalPart();
				}
			} else if (value is String) {
				number = String(value).replace(",",".");
				_value = parseFloat(number);
				this.text = number.replace(".", puntoVirgolaNotation);
				checkDecimalPart();
			} else {
				_value = NaN;
				this.text = "NaN";
			}
		}
		
		public function validate():Boolean {
			if (!isNaN(minValue) && !isNaN(maxValue)) {
				if ((Number(value)<=maxValue) && (Number(value)>=minValue)) {
					return true
				}
				return false;
			}
			else
				return true
		
		}
		
		
		[Inspectable(enumeration="dot,comma", defaultValue="dot")]
		public function get notation():String
		{
			return _notation;
		}
		
		[Inspectable(enumeration="dot,comma", defaultValue="dot")]
		public function set notation(value:String):void
		{
			_notation = value;
			if(value == "dot") puntoVirgolaNotation = ".";
			if(value == "comma") puntoVirgolaNotation = ",";
			
		}
		private function numberValid(event:ValidationResultEvent):void 
		{ 
			isValid = true; 
		
//			fieldsValidated = true; 
		} 
		
		private function numberInvalid(event:ValidationResultEvent):void 
		{ 
			
			isValid = false; 
//			fieldsValidated = true; 
		} 
		protected function changeEvent(event:Event):void{
			if(this.text.length > 0){
				if(stringEntry != null) this.text = stringEntry
				var stringNeg:String = "";
				var stringNotation:String = "";
				var boolNeg:Boolean = false;
				var boolNot:Boolean = false;
				var checkNegativ:Number = this.text.lastIndexOf("-");
				var checkNotation:Number = this.text.lastIndexOf(puntoVirgolaNotation);
				
				if(checkNegativ > 0 ){
					boolNeg = true;
					stringNeg = "-";
				} else if(checkNegativ == 0){
					stringNeg = "";
				}else{
					stringNeg = "-";
				}
				
				if(checkNotation == 0){
					boolNot = true;
					stringNotation = puntoVirgolaNotation;
				}else if(checkNotation != -1){
					if(checkNegativ == 0 && checkNotation == 1){
						boolNot = true;
						stringNotation = puntoVirgolaNotation;
					}else{
						stringNotation = "";
					}
				}else{
					stringNotation = puntoVirgolaNotation;
				}
				
				if(this.text.length == 1 && checkNegativ == 0) this.restrict = "0-9\\";
				else this.restrict = "0-9\\" + stringNeg + stringNotation;
				
				if(boolNeg) this.text = this.text.replace("-", "");
				if(boolNot) this.text = this.text.replace(puntoVirgolaNotation, "");
			}else{
				this.restrict = _restrictNumericText;
			}
//			if (Number(this.text)>maxValue) {
//				this.text=_oldValue;
//			} 
			
			checkDecimalPart();
		}
		
		protected function keyDownEvent(event:KeyboardEvent):void{
			var checkNegativ:Number = this.text.lastIndexOf("-");
			var checkNotation:Number = this.text.lastIndexOf(puntoVirgolaNotation);
			
			if(checkNegativ>0){
				//this.text = this.text.replace("-", "");
				while(checkNegativ != -1){
					checkNegativ = this.text.lastIndexOf("-");
					this.text = this.text.replace("-", "");
				}
				stringEntry = this.text;
				trace("keydown  " + this.text);
			}else{
				stringEntry = null;
			}
			
		}
		
		protected function keyUpEvent(event:KeyboardEvent):void{
			var checkNegativ:Number = this.text.lastIndexOf("-");
			var checkNotation:Number = this.text.lastIndexOf(puntoVirgolaNotation);
			var checkFirstNotation:Number = this.text.indexOf(puntoVirgolaNotation);
			if(checkNegativ>0){
				this.text = this.text.replace("-", "");
			}
			
		}
		
		private function checkDecimalPart():void{
			if(_sizeDecimalPart != -1 && this.text.length > 0){
				var checkNotation:Number = this.text.lastIndexOf(puntoVirgolaNotation);
				var lunghezza:Number = this.text.length;
				if(checkNotation != -1){
					if((this.text.length - (checkNotation + 1)) > _sizeDecimalPart){
						this.text = this.text.substr(0, checkNotation + (_sizeDecimalPart + 1));
					}	
				}
			}
			// aggiorno il valore numerico
			if (this.text == "") {
				_value = NaN;
			} else if (this.text == "-"){
				_value = -0;
			} else {
				var number:String = this.text;
				number = number.replace(",",".");
				_value = parseFloat(number);
			}
			_oldValue=this.text;
			this.selectRange(this.text.length,this.text.length)
		}    
		
		public function updateValue(value:Object):void {
			trace("Updading value from model object");
			this.value=value;
		}
		
		public function get componentValue():Object {
			trace("Getting value from component");
			return this.value;
		}		
		
	}
}